package com.edevp.common.mybatis.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.edevp.common.core.util.CommonUtil;
import com.edevp.common.core.util.date.DateUtil;
import com.edevp.common.core.util.reflect.ReflectUtil;
import com.edevp.common.mybatis.annotation.CacheEntity;
import com.edevp.common.mybatis.dto.PageDTO;
import com.edevp.common.mybatis.entity.BaseEntity;
import com.edevp.common.mybatis.mapper.BaseMapper;
import com.edevp.common.mybatis.mapper.Wrapper;
import com.edevp.common.mybatis.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.ParameterizedType;
import java.util.Date;
import java.util.List;

/**
 * @author Lean
 * @create 2020-02-16 10:00 PM
 **/
public abstract class BaseServiceImpl<T extends BaseEntity,M extends BaseMapper<T>> implements BaseService<T> {


	protected M mapper;
	public M getMapper() {
		return mapper;
	}

	@Autowired
	public void setMapper(M mapper) {
		this.mapper = mapper;
	}



	@Override
	@SuppressWarnings("unchecked")
	public T get(String id){
		Date start = DateUtil.getDate();
		String key = getCacheKey();
		Object o = null;
		if(CommonUtil.isNotNull(key)){
			/*o = OrmUtil.getEntity(key+id);
			if(o == null){
				o = mapper.selectById(id);
				if(o != null){
					OrmUtil.putEntity(key+id,o);
				}
			}*/
		}else{
			o = mapper.selectById(id);
		}

		Date end = DateUtil.getDate();
		System.out.println("----get--查询耗时-----"+ (end.getTime()-start.getTime()));

		return (T)o;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int insert(T entity){
		entity.doBeforeInsert();
		return mapper.insert(entity);
	}
	@Override
	@Transactional(rollbackFor = Exception.class)
	public int update(T entity){
		String key = getCacheKey();
		if(CommonUtil.isNotNull(key)){
//			OrmUtil.delEntity(key+entity.getId());
		}
		entity.doBeforeUpdate();
		return mapper.updateById(entity);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int delete(String id){
		return deleteByPrimaryKey(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int deleteByPrimaryKey(String id){
		String key = getCacheKey();
		if(CommonUtil.isNotNull(key)){
//			OrmUtil.delEntity(key+id);
		}
		return mapper.deleteById(id);
	}

	@Override
	public List<T> findAll(){
		return mapper.selectList(null);
	}

	@Override
	public T findOne(Wrapper<T> wrapper){
		List<T> data = mapper.selectList(wrapper);
		if(data != null && data.size()>0){
			return data.get(0);
		}
		return null;
	}
	@Override
	public List<T> find(Wrapper<T> wrapper){
		return mapper.selectList(wrapper);
	}
	@Override
	public PageDTO<T> findByPage(int pageIndex, int pageSize){
		return findByPage(pageIndex, pageSize,null);
	}
	@Override
	public PageDTO<T> findByPage(int pageIndex, int pageSize, Wrapper<T> wrapper){
		IPage<T> page = mapper.selectPage(new Page<>(pageIndex,pageSize),wrapper);
		return new PageDTO<>(page.getTotal(),page.getRecords(),page.getPages(),pageSize);

	}

	private String getCacheKey(){
		String key = "";
		Class<T> clazz = getClazz();
		if(clazz != null){
			if(ReflectUtil.hasAnnotation(clazz, CacheEntity.class)){
				key = clazz.getSimpleName()+":";
			}

		}
		return key;
	}

	/**
	 * 获取泛型对相应的Class对象
	 * @author 刘朋
	 * <br/>date 2018-11-12
	 */
	@SuppressWarnings("unchecked")
	private Class<T>  getClazz(){
		// 返回表示此 Class 所表示的实体（类、接口、基本类型或 void）的直接超类的 Type。
		ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
		// 返回表示此类型实际类型参数的 Type 对象的数组()，想要获取第二个泛型的Class，所以索引写1
		return (Class<T>)type.getActualTypeArguments()[0];
	}
}